package com.last1mile.web.control;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import com.last1mile.commons.PwdEnDe;
import com.last1mile.model.Login;
import com.last1mile.pojo.UserDO;
import com.last1mile.service.UserService;
import com.last1mile.validator.LoginValidator;

@Controller
@RequestMapping(value = "/security/*")
@SessionAttributes("currentLogin")
public class SecurityController {

    @Autowired
    @Qualifier("loginValidator")
    LoginValidator  loginValidator;

    @Autowired
    @Qualifier("userServiceImpl")
    UserService     userService;

    @Autowired
    @Qualifier("pwdEnDe")
    private PwdEnDe pwdEnDe;

    @RequestMapping(value = "/login.html", method = RequestMethod.GET)
    public String initForm(@ModelAttribute("login") Login login, HttpServletRequest request, ModelMap model) {
        return "LoginForm";
    }

    @RequestMapping(value = "/login.html", method = RequestMethod.POST)
    public String login(@ModelAttribute("login") Login login, BindingResult result, HttpServletRequest request,
                        ModelMap model) throws Exception {
        loginValidator.validate(login, result);
        if (result.hasErrors()) {
            return "LoginForm";
        } else {
            UserDO userDo = userService.queryUserByLoginId(login.getLoginId());
            if (userDo != null) {
                String correctPwd = pwdEnDe.decrypt(userDo.getLoginPwd(), userDo.getPwdKey());
                if (StringUtils.equals(login.getLoginPwd(), correctPwd)) {
                    this.setLogin(login.getLoginId(), login.getLoginPwd());

                    login.setUserId(userDo.getId());
                    login.setCoutryCode("001");// TODO 当前设置成缺省值：中国代码001 以后要改成用户注册用的地址
                    model.addAttribute("currentLogin", login);

                    return "redirect:/u/" + login.getLoginId() + "/profile.html";
                } else {
                    return "LoginForm";
                }
            } else {
                return "LoginForm";
            }
        }
    };

    private final void setLogin(String loginId, String password) {
        Subject currentUser = SecurityUtils.getSubject();

        if (!currentUser.isAuthenticated()) {
            // collect user principals and credentials in a gui specific manner
            // such as username/password html form, X509 certificate, OpenID,
            // etc.
            // We'll use the username/password example here since it is the most
            // common.
            // (do you know what movie this is from? ;)
            UsernamePasswordToken token = new UsernamePasswordToken(loginId, password);
            // this is all you have to do to support 'remember me' (no config -
            // built in!):
            token.setRememberMe(true);
            currentUser.login(token);
        }
    };

    @RequestMapping(value = "/loginSuccess.html")
    public String loginSuccess(ModelMap model) {
        return "LoginSuccess";
    };

    @RequestMapping(value = "/loginUnauthorized.html")
    public String loginUnauthorized(ModelMap model) {
        return "LoginUnauthorized";
    };

    @RequestMapping(value = "/logout.html")
    public String logout(HttpServletRequest request, SessionStatus status) {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        request.getSession().invalidate();
        status.setComplete();
        return "redirect:/index.html";
    };
}
